/**
 * @file hal_Industrial_vibration_sensor.c
 * @author fei_niao
 * @brief 工业振动传感器硬件抽象层
 * @version 1.1.0
 * @date 2025-05-01
 * @copyright Copyright (c) 2025 飞鸟
 *
 * @par 功能描述：
 * + 振动传感器数据采集（通过Modbus协议）
 * + 音频信号同步采集（ADC）
 * + 多通道DMA数据传输管理
 * + 健康状态预测数据预处理
 *
 * @par 硬件依赖：
 * - CH32V30x系列MCU
 * - USART2/UART4通信接口
 * - ADC音频接口（可选）
 * - TIM3定时器
 * - DMA1/DMA2控制器
 *
 * @versionhistory
 * | Version | Date       | Author     | Notes                |
 * |---------|------------|------------|----------------------|
 * | 1.0.0   | 2025-04-29 | fei_niao   | 初始版本             |
 * | 1.1.0   | 2025-05-01 | fei_niao   | 增加音频同步采集功能 |
 */


#include <ch32v30x_gpio.h>
#include "hal_Industrial_vibration_sensor.h"


void Dev1_DMA_Send(void* data, uint16_t len);
void Dev2_DMA_Send(void* data, uint16_t len);

//uint8_t uart3_dma_tx_buffer[DMA_TX_BUFFER_SIZE];
//uint8_t uart3_dma_rx_buffer[DMA_RX_BUFFER_SIZE];
uint8_t uart4_dma_tx_buffer[DMA_TX_BUFFER_SIZE];
uint8_t uart4_dma_rx_buffer[DMA_RX_BUFFER_SIZE];
uint8_t uart2_dma_rx_buffer[DMA_RX_BUFFER_SIZE];
char uart2_dma_tx_buffer[DMA_TX_BUFFER_SIZE];

volatile uint8_t Audio_Vibration_sample_synchronize_flag = 0;       // 音频、震动数据同步标志位


Project_Msg_Typedef Project_Msg;


#ifdef ADC_DEV_NEED
static AD_Device_Typedef adc_dev1 = {
        .port = GPIOA,
        .pin = GPIO_Pin_1,
        .adcx = ADC1,
        .adc_sampleTime = ADC_SampleTime_55Cycles5,
        .adc_rank = 1,
        .adc_channelx = ADC_Channel_1,
        .ADC_ScanConvMode = DISABLE,
        .ADC_ContinuousConvMode = DISABLE,
        .ADC_DataAlign = ADC_DataAlign_Right,
        .ADC_ExternalTrigConv = ADC_ExternalTrigConv_None,
        .ADC_NbrOfChannel = 1,
        .ADC_Mode = ADC_Mode_Independent,
        .Full_voltage = 3.3,
        .ADC_clock_source = RCC_PCLK2_Div6
};
#endif

static UART_Device_Typedef dev2 = {
        .UARTx = UART4,
        .port = GPIOC,
        .tx_pin = GPIO_Pin_10,
        .rx_pin = GPIO_Pin_11,
        .gpio_tx_pin_mode = GPIO_Mode_AF_PP,
        .gpio_rx_pin_mode = GPIO_Mode_IN_FLOATING,
        .BaudRate = 9600,
        .StopBits = USART_StopBits_1,
        .WordLength = USART_WordLength_8b,
        .Parity = USART_Parity_No,
        .HardwareFlowControl = USART_HardwareFlowControl_None,
        .Mode = USART_Mode_Tx | USART_Mode_Rx,
        .TX_DMAx_Channely = DMA2_Channel5,
        .RX_DMAx_Channely = DMA2_Channel3,
        .USART_DMAReq = USART_DMAReq_Tx | USART_DMAReq_Rx,

        .USART_IT = USART_IT_IDLE,

        .NVIC_IRQChannel = UART4_IRQn,
        .NVIC_IRQChannelCmd = ENABLE,
        .NVIC_IRQChannelPreemptionPriority = 1,
        .NVIC_IRQChannelSubPriority = 1,

        .RCC_APB1Periph = RCC_APB1Periph_UART4,
        .RCC_APB2Periph = RCC_APB2Periph_GPIOC,
        .RCC_APB1PeriphClockCmd = RCC_APB1PeriphClockCmd,
        .RCC_APB2PeriphClockCmd = RCC_APB2PeriphClockCmd,

        .Data_Send_Func = Dev2_DMA_Send
};


static UART_Device_Typedef dev1 = {
        .UARTx = USART2,
        .port = GPIOA,
        .tx_pin = GPIO_Pin_2,
        .rx_pin = GPIO_Pin_3,
        .gpio_tx_pin_mode = GPIO_Mode_AF_PP,
        .gpio_rx_pin_mode = GPIO_Mode_IN_FLOATING,
        .BaudRate = 115200,
        .StopBits = USART_StopBits_1,
        .WordLength = USART_WordLength_8b,
        .Parity = USART_Parity_No,
        .HardwareFlowControl = USART_HardwareFlowControl_None,
        .Mode = USART_Mode_Tx | USART_Mode_Rx,
        .TX_DMAx_Channely = DMA1_Channel6,
        .RX_DMAx_Channely = DMA1_Channel7,
        .USART_DMAReq = USART_DMAReq_Tx | USART_DMAReq_Rx,

        .USART_IT = USART_IT_IDLE,

        .NVIC_IRQChannel = USART2_IRQn,
        .NVIC_IRQChannelCmd = ENABLE,
        .NVIC_IRQChannelPreemptionPriority = 1,
        .NVIC_IRQChannelSubPriority = 1,

        .RCC_APB1Periph = RCC_APB1Periph_USART2,
        .RCC_APB2Periph = RCC_APB2Periph_GPIOA,
        .RCC_APB1PeriphClockCmd = RCC_APB1PeriphClockCmd,
        .RCC_APB2PeriphClockCmd = RCC_APB2PeriphClockCmd,

        .Data_Send_Func = Dev1_DMA_Send
};


static Device_DMA_Typedef dev2_dma_rx = {
        .DMA_PeripheralBaseAddr = (u32)(&UART4->DATAR),
        .DMA_MemoryBaseAddr = (u32)uart4_dma_rx_buffer,
        .DMA_DIR = DMA_DIR_PeripheralSRC,
        .DMA_BufferSize = sizeof(uart4_dma_rx_buffer),
        .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
        .DMA_MemoryInc = DMA_MemoryInc_Enable,
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
        .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
        .DMA_Mode = DMA_Mode_Normal,
        .DMA_Priority = DMA_Priority_Low,
        .DMA_M2M = DMA_M2M_Disable,

        .DMAx_Channely = DMA2_Channel3,

        .RCC_AHBPeriph = RCC_AHBPeriph_DMA2,
        .RCC_AHBPeriphClockCmd = RCC_AHBPeriphClockCmd,
};

static Device_DMA_Typedef dev2_dma_tx = {
        .DMA_PeripheralBaseAddr = (u32)(&UART4->DATAR),
        .DMA_MemoryBaseAddr = (u32)uart4_dma_tx_buffer,
        .DMA_DIR = DMA_DIR_PeripheralDST,
        .DMA_BufferSize = sizeof(uart4_dma_tx_buffer),
        .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
        .DMA_MemoryInc = DMA_MemoryInc_Enable,
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
        .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
        .DMA_Mode = DMA_Mode_Normal,
        .DMA_Priority = DMA_Priority_Low,
        .DMA_M2M = DMA_M2M_Disable,

        .DMAx_Channely = DMA2_Channel5,

        .RCC_AHBPeriph = RCC_AHBPeriph_DMA2,
        .RCC_AHBPeriphClockCmd = RCC_AHBPeriphClockCmd,

        .DMAy_FLAG = DMA2_FLAG_TC5
};

static Device_DMA_Typedef dev1_dma_tx = {
        .DMA_PeripheralBaseAddr = (u32)(&USART2->DATAR),
        .DMA_MemoryBaseAddr = (u32)uart2_dma_tx_buffer,
        .DMA_DIR = DMA_DIR_PeripheralDST,
        .DMA_BufferSize = sizeof(uart2_dma_tx_buffer),
        .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
        .DMA_MemoryInc = DMA_MemoryInc_Enable,
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
        .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
        .DMA_Mode = DMA_Mode_Normal,
        .DMA_Priority = DMA_Priority_Low,
        .DMA_M2M = DMA_M2M_Disable,

        .DMAx_Channely = DMA1_Channel7,

        .RCC_AHBPeriph = RCC_AHBPeriph_DMA1,
        .RCC_AHBPeriphClockCmd = RCC_AHBPeriphClockCmd,
        .DMAy_FLAG = DMA1_FLAG_TC7
};

static Device_DMA_Typedef dev1_dma_rx = {
        .DMA_PeripheralBaseAddr = (u32)(&USART2->DATAR),
        .DMA_MemoryBaseAddr = (u32)uart2_dma_rx_buffer,
        .DMA_DIR = DMA_DIR_PeripheralSRC,
        .DMA_BufferSize = sizeof(uart2_dma_rx_buffer),
        .DMA_PeripheralInc = DMA_PeripheralInc_Disable,
        .DMA_MemoryInc = DMA_MemoryInc_Enable,
        .DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte,
        .DMA_MemoryDataSize = DMA_MemoryDataSize_Byte,
        .DMA_Mode = DMA_Mode_Normal,
        .DMA_Priority = DMA_Priority_Low,
        .DMA_M2M = DMA_M2M_Disable,

        .DMAx_Channely = DMA1_Channel6,

        .RCC_AHBPeriph = RCC_AHBPeriph_DMA1,
        .RCC_AHBPeriphClockCmd = RCC_AHBPeriphClockCmd,
};


static BSP_Timer_TypeDef t = {
        .TIMx = TIM3,

        .RCC_APBxPeriph_TIMy = RCC_APB1Periph_TIM3,
        .RCC_APBxPeriphClockCmd = RCC_APB1PeriphClockCmd,

        .TIM_ClockDivision = TIM_CKD_DIV1,
        .TIM_CounterMode = TIM_CounterMode_Up,
        .TIM_Period = 999,
        .TIM_Prescaler = 6 - 1,
        .TIM_RepetitionCounter = 0,

        .TIM_FLAG = TIM_IT_Update,
        .TIM_IT = TIM_IT_Update,

        .NVIC_PriorityGroupx = NVIC_PriorityGroup_2,

        .NVIC_IRQChannel = TIM3_IRQn,
        .NVIC_IRQChannelCmd = ENABLE,
        .NVIC_IRQChannelPreemptionPriority = 2,
        .NVIC_IRQChannelSubPriority = 1
};


/**
 * @brief 初始化传感器相关外设
 * @note 包括UART4、ADC、I2S（可选）及对应DMA通道
 */
void Sensor_Init(void) {
    BSP_USART_Init(&dev2);
#ifdef ADC_DEV_NEED
    Timer_Init(&t);         // 定时采样
    BSP_ADC_Init(&adc_dev1);
#endif
    BSP_DMA_INIT(&dev2_dma_rx);
    BSP_DMA_INIT(&dev2_dma_tx);

}


/**
 * @brief 初始化通信外设
 * @note 配置USART2及其DMA通道
 */
void Communication_Init(void) {
    BSP_USART_Init(&dev1);
    BSP_DMA_INIT(&dev1_dma_rx);
    BSP_DMA_INIT(&dev1_dma_tx);
}


/**
 * @brief 通过USART2 DMA发送数据
 * @param data 待发送数据指针
 * @param len 数据长度（字节）
 */
void Dev1_DMA_Send(void* data, uint16_t len)
{
    // ​​必须先等待上一次DMA传输完成，再关闭DMA通道​​
    while(DMA_GetFlagStatus(dev1_dma_tx.DMAy_FLAG) == RESET); /* Wait until USART2 TX DMA1 Transfer Complete */
    // 关闭DMA通道
    DMA_Cmd(dev1_dma_tx.DMAx_Channely, DISABLE);

    printf("\r\nUSART2_DMA_IS_Sending\r\n");

    // 复制数据到发送缓冲区
    len = (len > DMA_TX_BUFFER_SIZE) ? DMA_TX_BUFFER_SIZE : len;
    memcpy(uart2_dma_tx_buffer, data, len);
    //    for (int i = 0; i < len; i++ ) {
//        printf("0x%02X ", uart2_dma_tx_buffer[i]);
//    }
//    printf("\r\n");

    DMA_SetCurrDataCounter(dev1_dma_tx.DMAx_Channely, len);
    DMA_Cmd(dev1_dma_tx.DMAx_Channely, ENABLE);

//        // CH32上可以不要这个
//     // 使能USART2的DMA传输请求
//    USART_DMACmd(USART2, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
}


/**
 * @brief 通过UART4 DMA发送数据
 * @param data 待发送数据指针
 * @param len 数据长度（字节）
 */
void Dev2_DMA_Send(void* data, uint16_t len)
{
    // 等待上一次DMA传输完成
    while(DMA_GetFlagStatus(dev2_dma_tx.DMAy_FLAG) == RESET);
    // 关闭DMA通道
    DMA_Cmd(dev2_dma_tx.DMAx_Channely, DISABLE);

    printf("\r\nUART4_DMA_Send:\r\n");

    // 复制数据到发送缓冲区
    len = (len > DMA_TX_BUFFER_SIZE) ? DMA_TX_BUFFER_SIZE : len;
     memcpy(uart4_dma_tx_buffer, data, len);
    for (int i = 0; i < len; i++ ) {
        printf("0x%02X ", uart4_dma_tx_buffer[i]);
    }
    printf("\r\n");

    DMA_SetCurrDataCounter(dev2_dma_tx.DMAx_Channely, len);
    DMA_Cmd(dev2_dma_tx.DMAx_Channely, ENABLE);

//    // CH32上可以不要这个
//    // 使能UART4的DMA传输请求
//    USART_DMACmd(UART4, USART_DMAReq_Tx | USART_DMAReq_Rx, ENABLE);
}




/**
 * @brief 向传感器设备发送数据
 * @param data 待发送数据指针
 * @param len 数据长度（字节）
 */
void SendData_To_Sensor(void* data, uint16_t len) {
    dev2.Data_Send_Func(data, len);
}


/**
 * @brief 向通信设备发送数据
 * @param data 待发送数据指针
 * @param len 数据长度（字节）
 */
void SendData_To_CommunicationDev(void* data, uint16_t len) {
    dev1.Data_Send_Func(data, len);
}


/**
 * @brief Modbus CRC16 校验计算
 * @param data 数据指针
 * @param len 数据长度
 * @return CRC16 校验值
 */
uint16_t Modbus_CRC16(const uint8_t* data, uint16_t len) {
    uint16_t crc = 0xFFFF;
    while (len--) {
        crc ^= *data++;
        for (uint8_t i = 0; i < 8; i++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }
    return crc;
}


/**
 * @brief 构建读取保持寄存器指令 (0x03)
 * @param cmd 指令缓冲区(至少8字节)
 * @param slave_addr 从机地址
 * @param reg_addr 寄存器起始地址
 * @param RegNum 要读取的寄存器数量
 */
void Modbus_Build_Read_Cmd(uint8_t* cmd, uint16_t slave_addr,
                            uint16_t reg_addr, uint16_t RegNum) {
    cmd[0] = (uint8_t)slave_addr;
    cmd[1] = FUNC_CODE_READ; // 功能码：读保持寄存器
    cmd[2] = (uint8_t)(reg_addr >> 8);
    cmd[3] = (uint8_t)reg_addr;
    cmd[4] = (uint8_t)(RegNum >> 8);
    cmd[5] = (uint8_t)RegNum;
    uint16_t crc = Modbus_CRC16(cmd, 6);
    cmd[6] = crc & 0xFF; // CRC 低字节
    cmd[7] = crc >> 8; // CRC 高字节
}


/**
 * @brief 构建写入单个寄存器指令 (0x06)
 * @param cmd 指令缓冲区(至少8字节)
 * @param slave_addr 从机地址
 * @param reg_addr 寄存器地址
 * @param Written_Value 要写入的值
 */
void Modbus_Build_Write_Cmd(uint8_t* cmd, uint16_t slave_addr,
                            uint16_t reg_addr, uint16_t Written_Value) {
    cmd[0] = (uint8_t)slave_addr;
    cmd[1] = FUNC_CODE_WRITE; // 功能码：写单个寄存器
    cmd[2] = (uint8_t)(reg_addr >> 8);
    cmd[3] = (uint8_t)reg_addr;
    cmd[4] = (uint8_t)(Written_Value >> 8);
    cmd[5] = (uint8_t)Written_Value;
    uint16_t crc = Modbus_CRC16(cmd, 6);
    cmd[6] = crc & 0xFF; // CRC 低字节
    cmd[7] = crc >> 8; // CRC 高字节
}

/**
 * @brief 执行传感器操作（读/写）
 * @param Action 操作类型（READ/WRITE）
 * @param slave_addr 从机地址
 * @param reg_addr 寄存器地址
 * @param temp 读模式时为寄存器数量，写模式时为写入值
 */
void SensorOp(SensorActionType Action, uint8_t slave_addr, uint16_t reg_addr, uint16_t temp) {
    uint8_t Cmd[8];

    switch(Action) {
        case READ:  Modbus_Build_Read_Cmd(Cmd, slave_addr, reg_addr, temp); break;
        case WRITE: Modbus_Build_Write_Cmd(Cmd, slave_addr, reg_addr, temp); break;
    }

    SendData_To_Sensor(Cmd, 8);
}


/**
 * @brief 解析传感器返回数据
 * @note 处理Modbus协议数据，提取振动传感器各轴RMS值
 */
void Sensor_Data_Perse (void) {
    // 获取实际接收到的数据长度
    uint16_t received_len = DMA_RX_BUFFER_SIZE - DMA_GetCurrDataCounter(dev2_dma_rx.DMAx_Channely);

    printf("\r\nUART4 DMA RX (%d bytes): ", received_len);
    for (uint16_t i = 0; i < received_len; i++)
    {
        printf("0x%02X ", uart4_dma_rx_buffer[i]);
    }
    printf("\r\n");

    // 数据CRC校验
    uint16_t calc_crc = Modbus_CRC16(uart4_dma_rx_buffer, received_len - 2);
    uint16_t recv_crc = (uart4_dma_rx_buffer[received_len-1] << 8) | uart4_dma_rx_buffer[received_len-2];
    if (calc_crc != recv_crc) {
        printf("crc err\r\n");
    }

    // 提取数据
    int data_num = (int)uart4_dma_rx_buffer[2];
    if (data_num != 14) {
        printf("recive err\r\n");
    }


    // 等待音频数据完成后再解析打包振动传感器数据
    if (Audio_Vibration_sample_synchronize_flag) {
        // 解析振动传感器数据
        memcpy(Project_Msg.VibrationMonitorRawData, uart4_dma_rx_buffer, received_len * sizeof(uint8_t)); // 震动原始数据

        uint16_t x_v_rms = uart4_dma_rx_buffer[3] << 8 | uart4_dma_rx_buffer[4];
        Project_Msg.Expected_Data.x_v_rms = (float)(x_v_rms/100.0);

        uint16_t y_v_rms = uart4_dma_rx_buffer[5] << 8 | uart4_dma_rx_buffer[6];
        Project_Msg.Expected_Data.y_v_rms = (float)(y_v_rms/100.0);

        uint16_t z_v_rms = uart4_dma_rx_buffer[7] << 8 | uart4_dma_rx_buffer[8];
        Project_Msg.Expected_Data.z_v_rms = (float)(z_v_rms/100.0);

        uint16_t temperature = uart4_dma_rx_buffer[9] << 8 | uart4_dma_rx_buffer[10];
        Project_Msg.Expected_Data.temperature = (float)(temperature/100.0);

        uint16_t x_acc_rms = uart4_dma_rx_buffer[11] << 8 | uart4_dma_rx_buffer[12];
        Project_Msg.Expected_Data.x_acc_rms = (float)(x_acc_rms/100.0);

        uint16_t y_acc_rms = uart4_dma_rx_buffer[13] << 8 | uart4_dma_rx_buffer[14];
        Project_Msg.Expected_Data.y_acc_rms = (float)(y_acc_rms/100.0);

        uint16_t z_acc_rms = uart4_dma_rx_buffer[15] << 8 | uart4_dma_rx_buffer[16];
        Project_Msg.Expected_Data.z_acc_rms = (float)(z_acc_rms/100.0);

        Audio_Vibration_sample_synchronize_flag = 0;   // 允许音频采样
    }

    // 清空 DMA 缓冲区内容
    memset(uart4_dma_rx_buffer, 0, DMA_RX_BUFFER_SIZE);
}


void extract_json_simple(const char *input, char *output) {
    const char *start = strchr(input, '{'); // 查找第一个{

    if (start != NULL) {
        strcpy(output, start); // 复制从{开始的所有内容
    } else {
        output[0] = '\0'; // 没有找到{则返回空字符串
    }
}


/**
 * @brief 解析通信设备返回数据
 * @note 清空USART2接收缓冲区
 */
void CommunicationDev_Data_Perse(void) {

    uint16_t received_len = DMA_RX_BUFFER_SIZE - DMA_GetCurrDataCounter(dev1_dma_rx.DMAx_Channely);
    received_len = (received_len > DMA_RX_BUFFER_SIZE) ? DMA_RX_BUFFER_SIZE : received_len;

    CH32_LOGI(CommunicationDeviceTAG, "USART DMA RX (%d bytes)", received_len);


    static char temp_buf[DMA_RX_BUFFER_SIZE + 1] = {0};
    static char fixed_buf[DMA_RX_BUFFER_SIZE + 1] = {0};
    if (received_len > 0) {
        uint16_t copy_len = (received_len < DMA_RX_BUFFER_SIZE) ? received_len : DMA_RX_BUFFER_SIZE;

        memcpy(temp_buf, uart2_dma_rx_buffer, copy_len);
        temp_buf[copy_len] = '\0';
        CH32_LOGI(CommunicationDeviceTAG, "RX : %s", temp_buf);


        extract_json_simple(temp_buf, fixed_buf);
        if (fixed_buf[0] == '\0') {
            CH32_LOGW("CommunicationDev_Data_Perse", "No Json Msg");
            memset(fixed_buf, 0, DMA_RX_BUFFER_SIZE);
            goto cleanup;
        }

        // JSON解析
        cJSON *root = cJSON_Parse(temp_buf);
        if (root != NULL) {
            cJSON* cmd = cJSON_GetObjectItemCaseSensitive(root, "type");
            if (strcmp(cmd->valuestring, "update") == 0) {
                cJSON* device_id = cJSON_GetObjectItemCaseSensitive(root, "device_id");
                OTA_Update_Cmd_Typedef update_cmd = {0};
                strcpy(update_cmd.type, cmd->valuestring);
                strcpy(update_cmd.device_id, device_id->valuestring);
                CH32_LOGI("CommunicationDev_Data_Perse", "update_dev_id: %s", update_cmd.device_id);
                xQueueSend(OTA_Update_Cmd_Queue, &update_cmd, pdMS_TO_TICKS(50));
            }
            cJSON_Delete(root);
        }
    }

cleanup:
    memset(uart2_dma_rx_buffer, 0, DMA_RX_BUFFER_SIZE);
    memset(temp_buf, 0, DMA_RX_BUFFER_SIZE);
    memset(fixed_buf, 0, DMA_RX_BUFFER_SIZE);
}

/* 中断处理函数组 */
/**
 * @brief USART2中断服务程序
 * @note 处理空闲中断，触发通信设备数据解析
 */
void USART2_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void USART2_IRQHandler(void) {
    if (USART_GetITStatus(USART2, USART_IT_IDLE) != RESET)
    {
        DMA_Cmd(DMA1_Channel6, DISABLE);

        CommunicationDev_Data_Perse();

        DMA_SetCurrDataCounter(DMA1_Channel6, DMA_RX_BUFFER_SIZE);
        DMA_Cmd(DMA1_Channel6, ENABLE);


        volatile uint32_t temp;  // 读SR+DR清除空闲中断标志
        temp = USART2->STATR;
        temp = USART2->DATAR;
        (void)temp;
//          下面方法也一样的
//        USART_ReceiveData(USART2);
//        USART_ClearFlag(USART2, USART_IT_IDLE);
    }
}


/**
 * @brief USART4中断服务程序
 * @note 处理空闲中断，触发传感器数据解析
 */
void UART4_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void UART4_IRQHandler(void)
{
    if (USART_GetITStatus(UART4, USART_IT_IDLE) != RESET)
    {
        DMA_Cmd(dev2.RX_DMAx_Channely, DISABLE);

        Sensor_Data_Perse();    // 解析数据

        DMA_SetCurrDataCounter(dev2.RX_DMAx_Channely, DMA_RX_BUFFER_SIZE);
        DMA_Cmd(dev2.RX_DMAx_Channely, ENABLE);


        volatile uint32_t temp;  // 读SR+DR清除空闲中断标志
        temp = UART4->STATR;
        temp = UART4->DATAR;
        (void)temp;
    }
}



/**
 * @brief TIM3中断服务程序
 * @note 定时采集ADC音频数据，触发同步标志
 */
static int i = 0;
void TIM3_IRQHandler(void) __attribute__((interrupt("WCH-Interrupt-fast")));
void TIM3_IRQHandler(void)
{
    if(TIM_GetITStatus(TIM3,TIM_IT_Update) == SET)
    {
        // op
        if (!Audio_Vibration_sample_synchronize_flag) {
            Project_Msg.AudioRawData[i] = Get_AD_Value(&adc_dev1);
            i++;
            if (i >= AD_RECEIVE_BUFFER_SIZE) {
                Audio_Vibration_sample_synchronize_flag = 1;
                i = 0;
            }
        }

        TIM_ClearITPendingBit(TIM3,TIM_IT_Update);
    }
}

